import {Component, OnInit, Input} from '@angular/core';
import {UtilComponent} from '../../interface/util-component.interface';
import {NzMessageService} from 'ng-zorro-antd';
import {FormBuilder, FormGroup, Validators} from '@angular/forms';
import {DrawFeatureService} from './draw-feature.service';
import {DrFeaService} from './dr-fea.service';
import Map from 'ol/Map';
import View from 'ol/View';
import {Circle as CircleStyle, Fill, Stroke, Style} from 'ol/style';
import GeoJSON from 'ol/format/GeoJSON';
import {Modify, Snap, Select} from 'ol/interaction';
import Draw from 'ol/interaction/Draw';
import DragPan from 'ol/interaction/DragPan';
import {Vector as VectorSource} from 'ol/source';
import {Vector as VectorLayer} from 'ol/layer';
import Feature from 'ol/Feature.js';
import {LineString, Point, Polygon} from 'ol/geom.js';
import {fromLonLat, getTransform} from 'ol/proj';
import {getArea, getLength} from 'ol/sphere';

declare let turf: any;

@Component({
    selector: 'kylin-draw-feature',
    templateUrl: './draw-feature.component.html',
    styleUrls: ['./draw-feature.component.less']
})
export class DrawFeatureComponent implements OnInit, UtilComponent {
    // ---------- 接口实现 begin -------------- //
    hasContent = true;
    map: Map;
    view: View;

    @Input() set data(val) {
        Object.assign(this, val);
        this.layerID = val.drawLayerId;
    };

    // ---------- 接口实现 end ---------------- //
    // 地图变量
    feature: any;
    draw: any;
    snap: any;
    modify: any;
    init = false;
    geo: any;
    //  数据 业务变量
    addFeatureModel = false;
    tabArr = this.drawFeatureService.returnTabArr();
    drawType: number;
    allLayersListData: any[] = []; // 最终图层GeoJson
    mapAllLayersListData: any[] = [];  // 地图所有实际的图层

    layeryShow: boolean;
    loading = false;
    layersForm: FormGroup;
    definLayer: any;
    definLayerJson: any;
    currentFeature: any; // 当前要素数据---Feature
    currentMaplayers: any; // 当前的地图真实图层---Layers
    currentLayer: any; // 当前数据图层---geojson
    currentProperties: any; // 属性---给当前要素加的属性
    showIcon = false;
    currentSelectFeature: any;
    currentSelectMapFeature;
    currentSelectMapFeatureColor;
    currSelectGeoLayer;
    currMapLayer;
    vectorLayer;
    select;
    currVisibilityMapLayer;
    layerID: string;
    nzSelectedIndex = 0;
    plyginLayersList: any = [];
    highlight;
    mergeFeature;
    featureMerge = [];
    mergefeatureCoorArray: any[] = []; // 需要被合并面的经纬度合集
    showMergeIcon = false;
    olUid;
    mapClickFun;
    showSplitSelectType = false;
    quiltSplitObject: any = {};
    splitObject: any = {};
    title = '';
    splitFeatureColor = undefined;
    tabStatus;
    output;
    splitList = [
        {
            title: '线拆分'
        },
    ];

    constructor(private drawFeatureService: DrawFeatureService,
                private dfService: DrFeaService,
                private fb: FormBuilder,
                private message: NzMessageService) {
    }

    ngOnInit() {
        if (this.layerID) {
            this.getEditLayers(this.layerID);  // 获取编辑图层
        } else {
            this.getSaveLayers();  // 获取图层列表
        }
        this.initMap();  // 初始化地图值
    }

    // 获取已发布之后编辑的图层
    getEditLayers(layerid) {
        this.drawFeatureService.getLayerDetail(layerid).then(res => {
            if (res.resp_code === '10000') {
                this.allLayersListData = res.data;
                this.appleMap(this.allLayersListData); // 渲染地图
                this.nzSelectedIndex = res.data[0].layerType - 1;
            } else {
                this.message.create('error', `列表请求失败`);
            }
        }).catch(err => {
            this.message.error('error', err);
        });
    }

    // 获取图层列表
    getSaveLayers() {
        this.drawFeatureService.layersList(0, '').then(res => {
            if (res.resp_code === '10000') {
                this.allLayersListData = res.data;
                this.appleMap(this.allLayersListData); // 渲染地图
                this.tabsDisable('');
            } else {
                this.message.create('error', `列表请求失败`);
            }
        }).catch(err => {
            this.message.error('error', err);
        });
    }

    // 数据渲染地图之前处理整合数据
    appleMap(geoJson) {
        // remove所有图层
        this.removeMapLayerAndInteraction();
        if (geoJson) {
            geoJson.map(data => {
                if (data.layerJson !== '{}') {
                    let geojsonObject;
                    if (typeof data.layerJson === 'string') {
                        geojsonObject = JSON.parse(data.layerJson);
                    } else if (typeof data.layerJson === 'object') {
                        geojsonObject = data.layerJson;
                    }
                    this.forLayer(geojsonObject).then(() => {
                        this.mapAllLayersListData = this.map.getLayers().getArray().slice(1); // get地图所有的点线面（业务图层）
                    })
                }
            })
        }
    }

    // 数据渲染地图
    forLayer(geojsonObject) {
        return new Promise((resolve) => {
            const vectorSource = new VectorSource({
                features: (new GeoJSON()).readFeatures(geojsonObject),
                wrapX: true
            });
            vectorSource.getFeatures().map((data) => {
                data.setStyle(this.setFeatureColor(data.getProperties().style));
            });
            this.vectorLayer = new VectorLayer({
                source: vectorSource,
            });
            this.map.addLayer(this.vectorLayer);
            resolve(this.map)
        })
    }

    // 退出绘制功能---清除所以的图层以及交互功能
    cancel(options?: any): any {
        this.removeMapLayerAndInteraction()
    }

    // 初始化地图
    initMap() {
        this.geo = new GeoJSON();
        this.view = this.map.getView();
    }

    // 选择 Tabs 触发点线面点击事件
    Select(args: any[]) {
        this.clickTabs(args[1].title);
    }

    // 点击点线面根据不同要素属性进行不同操作
    clickTabs(tabTitle: string) {
        this.initRemoveInteraction();
        // this.map.getInteractions().getArray().map(data => {
        //     this.map.removeInteraction(data);
        // });
        // const gragPan = new DragPan({});
        // this.map.addInteraction(gragPan);
        switch (tabTitle) {
            case '画点':
                if (this.dfService.judgePointLayers(this.allLayersListData, 1)) {
                    this.message.create('error', `请新建点图层`);
                } else {
                    this.initDrawPara(1, 'Point');
                }
                break;
            case '画线':
                if (this.dfService.judgePointLayers(this.allLayersListData, 2)) {
                    this.message.create('error', `请新建线图层`);
                } else {
                    this.initDrawPara(2, 'LineString');
                }
                break;
            case '画面':
                if (this.dfService.judgePointLayers(this.allLayersListData, 3)) {
                    this.message.create('error', `请新建面图层`);
                } else {
                    this.initDrawPara(3, 'Polygon');
                }
                break;
            case '合并':
                this.initMergeAndSplitPara(4);
                break;
            case '拆分':
                this.initMergeAndSplitPara(5);
                break;
            default:
                this.addFeatureModel = false;
        }
    }

    getMapAllLayryArrar() {
        this.initMergeParameter();
        for (let i = 0; i < this.allLayersListData.length; i++) {
            if (this.allLayersListData[i].layerType === 3) {
                this.plyginLayersList.push(this.allLayersListData[i]);
            }
        }
        this.allLayersListData = this.plyginLayersList;
        this.appleMap(this.allLayersListData); // geojson渲染地图

        if (this.allLayersListData.length === 0) {
            this.message.create('error', `目前没有区域可合并，请您新建区域图层`);
            return
        } else {
            this.tabsDisable(this.drawType);
            if (this.drawType === 4) { // 合并
                this.getPolygon();
            } else { // 拆分
                this.title = '请您在地图上选择要拆分的区域';
                this.splitPolygon();
            }
        }
    }

    splitPolygon() {
        this.quiltSplitObject = {};
        this.map.on('click', (evt) => {
            if (evt.dragging) {
                return;
            }
            if (this.quiltSplitObject.feature) { // 上一个选中要素的颜色还原  this.splitFeatureColor保存选中颜色
                this.quiltSplitObject.feature.setStyle(this.setFeatureColor(this.splitFeatureColor))
            }
            this.quiltSplitObject.feature = this.map.forEachFeatureAtPixel(evt.pixel, (featur: any) => {
                return featur
            });
            this.quiltSplitObject.layer = this.map.forEachLayerAtPixel(evt.pixel, (laye: any) => {
                return laye
            });
            if (!this.quiltSplitObject.feature) {
                this.message.create('error', `选中区域失败：请您重新选择区域`);
                return;
            } else if (this.writeGeo(this.quiltSplitObject.feature).geometry.type !== 'Polygon') {
                this.message.create('error', `选中区域失败：请您放大地图重新选择`);
                return;
            } else {
                this.splitFeatureColor = this.quiltSplitObject.feature.getStyle().getFill().getColor() || '#ffcc33';
                this.quiltSplitObject.feature.setStyle(this.setPlictFeatureColor('#a60a0abd'));
                this.showSplitSelectType = true;
                this.quiltSplitObject.geoFeature = this.writeGeo(this.quiltSplitObject.feature);
                this.title = '请您在下方 ↓ 选择拆分类型';
            }
        });
    }

    splitFun(tab) {
        this.unMapClickFun();
        if (tab[1].title === '线拆分') {
            this.addLin(this.quiltSplitObject.layer, 'LineString')
        } else {
            this.addLin(this.quiltSplitObject.layer, 'Polygon')
        }
    }


    addLin(layer, type) {
        return new Promise((resolve) => {
            this.draw = new Draw({
                source: layer.getSource(),
                style: new Style({
                    fill: new Fill({
                        color: '#a60a0abd'
                    }),
                    stroke: new Stroke({
                        color: '#a60a0abd',
                        width: 2
                    }),
                    image: new CircleStyle({
                        radius: 7,
                        fill: new Fill({
                            color: '#a60a0abd'
                        })
                    })
                }),
                type: type as any,
            });
            this.map.addInteraction(this.draw);
            resolve(this.draw)
        }).then((draw: any) => {
            draw.on('drawend', (e) => {
                this.splitObject.feature = e.feature;
                this.splitObject.geoFeature = this.writeGeo(this.splitObject.feature);
                this.map.removeInteraction(draw);
            });
        })
    }

    // 确定合并
    mergeFinish(type) {
        if (type === 4) {
            if (this.featureMerge.length === 0 || this.mergeFeature.length === 0) {
                this.message.create('error', `请选择需要合并的区域进行合并`);
                return
            }
            let confirmationMergerLayerList: any = {};
            const layer_Index = [];
            this.plyginLayersList.map(plygin => {
                plygin.layerJson.features.map((fea, i) => {
                    if (fea.id === this.mergeFeature.id) {
                        plygin.layerJson.features[i] = this.mergeFeature;
                        confirmationMergerLayerList = plygin
                    } else {
                        this.featureMerge.map((rr) => {
                            if (fea.id === rr.id) {
                                layer_Index.push(i)
                            }
                        })
                    }
                })
            });
            layer_Index.map(i => {
                confirmationMergerLayerList.layerJson.features.splice(i, 1);
            });
            this.editLayers(confirmationMergerLayerList);
            this.leaveMergeInit();
            this.allLayersListData = [];
            this.tabsDisable('')
        } else {
            const polygon = this.quiltSplitObject.geoFeature;
            const clipline = this.splitObject.geoFeature;
            if (!polygon) {
                this.message.create('error', `请先在地图上选择区域`);
                return;
            } else if (!clipline) {
                this.message.create('error', `请分割区域`);
                return;
            }
            this.polygonClipByLine(polygon, clipline)
        }
    }

    // 取消合并
    mergeClose(type) {
        if (type === 4) {
            this.leaveMergeInit();
            this.allLayersListData = [];
            this.getSaveLayers();
            this.tabsDisable('')
        } else {
            this.getSaveLayers();
            this.initSplitPolygin();
            this.unMapClickFun();
            this.tabsDisable('');
        }
    }


    polygonClipByLine(polygon, clipLine) {
        if (polygon.geometry.type === 'Polygon') {
            let polyLine = turf.polygonToLine(polygon); // 将面要素‎类转换成线‎要素类
            polyLine = turf.toWgs84(polyLine);
            clipLine = turf.toWgs84(clipLine);
            if (polygon.geometry.coordinates.length === 1) {
                if (polyLine.geometry.type === 'LineString') {
                    const polygonC = this.singlePolygonClip(polyLine, clipLine, 'LineString');
                    this.submitSplitPlygin(polygonC[0], polygonC[1]);
                }
            } else if (polygon.geometry.coordinates.length > 1) {
                this.multiPolygonClip(polyLine, clipLine);
            }
        } else if (polygon.geometry.type === 'MultiPolygon') {  // 如果被切割的多边形是环
            this.message.create('error', `裁剪失败:输入的多边形类型为错误`);
            this.errorInitSplit()
        } else {
            this.message.create('error', `裁剪失败:输入的多边形类型为错误`);
            this.errorInitSplit()
        }
    }

    multiPolygonClip(polyLine, clipLine) {
        // 将环 多边形分割成 内部逆时针多边形+外部多边形
        let aa = 0;
        polyLine.geometry.coordinates.map((coor, i) => {
            const multiPolygon = turf.lineString(coor);
            const intersect = turf.lineIntersect(multiPolygon, clipLine);
            if (intersect.features.length > 0) {   // 面与线有交点
                const resultPolygon = {
                    geometry: {coordinates: [], type: 'LineString'},
                    type: 'Feature',
                    properties: polyLine.properties
                };
                resultPolygon.geometry.coordinates = coor;
                const polygonClip: any = this.singlePolygonClip(resultPolygon, clipLine, 'MultiPolygon');
                polyLine.geometry.coordinates.splice(i, 1);

                const center = turf.center(polyLine);
                const center1 = turf.center(polygonClip[0]);
                const center2 = turf.center(polygonClip[1]);
                const options = {units: 'miles'};
                const distance1 = turf.distance(center, center1, options);
                const distance2 = turf.distance(center, center2, options);
                const splitOne = turf.lineToPolygon(polyLine);
                const splitTow = {
                    geometry: {coordinates: [], type: 'Polygon'},
                    type: 'Feature',
                    properties: polyLine.properties
                };
                if (distance1 < distance2) {
                    splitOne.geometry.coordinates.push(polygonClip[0].geometry.coordinates[0]); // 第一个
                    splitTow.geometry.coordinates.push(polygonClip[1].geometry.coordinates[0]);
                } else {
                    splitOne.geometry.coordinates.push(polygonClip[1].geometry.coordinates[0]); // 第一个
                    splitTow.geometry.coordinates.push(polygonClip[0].geometry.coordinates[0]);
                }
                this.submitSplitPlygin(splitOne, splitTow);
                return
            } else {
                aa++;
            }
            if (aa === polyLine.geometry.coordinates.length) {   // 面与线没有交点
                const splitPolyginAllCoord: any = this.polygonsMer(polyLine);
                const multiPolygon2 = turf.lineString(splitPolyginAllCoord.features[0].geometry.coordinates);
                const intersect5 = turf.lineIntersect(multiPolygon2, clipLine);
                if (intersect5.features.length <= 0) {
                    this.message.create('error', `裁剪失败:切割线不在裁剪多边形区域范围内`);
                    this.errorInitSplit();
                } else {
                    if (polyLine.geometry.coordinates.length > 2) {
                        this.message.create('error', `裁剪失败:要素个数超出范围`);
                        this.errorInitSplit();
                        return
                    } else { // 两个面的区域  线从中间切断
                        const resultPolygon1 = {
                            geometry: {coordinates: [], type: 'Polygon'},
                            type: 'Feature',
                            properties: {}
                        };
                        const resultPolygon2 = {
                            geometry: {coordinates: [], type: 'Polygon'},
                            type: 'Feature',
                            properties: {}
                        };
                        resultPolygon1.geometry.coordinates.push(polyLine.geometry.coordinates[0]);
                        resultPolygon2.geometry.coordinates.push(polyLine.geometry.coordinates[1]);
                        this.submitSplitPlygin(resultPolygon1, resultPolygon2);
                    }
                }
            }
        })
    }

    singlePolygonClip(polyLine, clipLine, type) { // 剪切面算法
        polyLine = turf.toWgs84(polyLine);
        clipLine = turf.toWgs84(clipLine);
        // 获得裁切点
        const intersects = turf.lineIntersect(polyLine, clipLine);
        if (intersects.features.length !== 2) {
            if (type === 'MultiPolygon') {
                return
            } else if (type === 'LineString') {
                this.message.create('error', `裁剪失败:切割线与多边形交点应该为2个,当前交点个数为` + intersects.features.length);
                this.errorInitSplit();
            }
        }
        // 检查切割线与多边形的位置关系（切割线的起点和终点不能落在多边形内部）
        const clipLineLength = clipLine.geometry.coordinates.length;
        const clipLineStartPoint = turf.point(clipLine.geometry.coordinates[0]);
        const clipLineEndPoint = turf.point(clipLine.geometry.coordinates[clipLineLength - 1]);
        const polygon = turf.polygon([polyLine.geometry.coordinates]);
        if (turf.booleanPointInPolygon(clipLineStartPoint, polygon) || turf.booleanPointInPolygon(clipLineEndPoint, polygon)) {
            this.message.create('error', `裁剪失败:切割线起点或终点不能在裁剪多边形内部`);
            this.errorInitSplit()
        }
        // 通过裁切点分割多边形（只能获得多边形的一部分）
        const slicedPolyLine = turf.lineSlice(intersects.features[0], intersects.features[1], polyLine);
        // 裁剪线分割保留多边形内部部分
        const slicedClipLine = turf.lineSlice(intersects.features[0], intersects.features[1], clipLine);
        // 重新拼接多边形存在对接的问题所以先进行判断如何对接裁剪的多边形和裁剪线
        const resultPolyline1 = this.connectLine(slicedPolyLine, slicedClipLine);
        // 闭合线来构造多边形
        resultPolyline1.geometry.coordinates.push(resultPolyline1.geometry.coordinates[0]);
        const resultPolygon1 = turf.lineToPolygon(resultPolyline1); // 第一个面
        // 构造切割的另一面多边形
        const firstPointOnLine = this.isOnLine(turf.point(polyLine.geometry.coordinates[0]), slicedPolyLine);
        const pointList = [];
        if (firstPointOnLine) {
            for (let i = 0; i < polyLine.geometry.coordinates.length; i++) {
                const coordinate = polyLine.geometry.coordinates [i];
                if (!this.isOnLine(turf.point(coordinate), slicedPolyLine)) {
                    pointList.push(coordinate)
                }
            }
        } else {
            let skipNum = 0; // 记录前面被跳过的点的个数
            let isStartPush = false;
            for (let i = 0; i < polyLine.geometry.coordinates.length; i++) {
                const coordinate = polyLine.geometry.coordinates[i];
                if (!this.isOnLine(turf.point(coordinate), slicedPolyLine)) {
                    if (isStartPush) {
                        pointList.push(coordinate)
                    } else {
                        skipNum++
                    }
                } else {
                    isStartPush = true;
                }
            }
            // 将前面跳过的点补充到点数组中
            for (let i = 0; i < skipNum; i++) {
                pointList.push(polyLine.geometry.coordinates [i])
            }
        }
        const slicedPolyLine_2 = turf.lineString(pointList);
        const resultPolyline2 = this.connectLine(slicedPolyLine_2, slicedClipLine);
        // 闭合线来构造多边形
        resultPolyline2.geometry.coordinates.push(resultPolyline2.geometry.coordinates [0]);
        const resultPolygon2 = turf.lineToPolygon(resultPolyline2);
        // return [resultPolygon1, resultPolygon2];
        return [turf.toMercator(resultPolygon1), turf.toMercator(resultPolygon2)];
    }

    /**
     * 连接两条线
     * 方法会将两条线段最近的一段直接连接
     */
    connectLine(line1, line2) {
        const line2_length = line2.geometry.coordinates.length;
        const line1_startPoint = line1.geometry.coordinates[0];
        const line2_startPoint = line2.geometry.coordinates[0];
        const line2_endPoint = line2.geometry.coordinates[line2_length - 1];
        const pointList = [];
        // 获取line1 所有点坐标
        for (let i = 0; i < line1.geometry.coordinates.length; i++) {
            const coordinate = line1.geometry.coordinates[i];
            pointList.push(coordinate)
        }
        // 判断两条线的 起点是否接近，如果接近 逆转line2线 进行连接
        if (turf.distance(line1_startPoint, line2_startPoint) < turf.distance(line1_startPoint, line2_endPoint)) {
            line2.geometry.coordinates = line2.geometry.coordinates.reverse();
        }
        for (let i = 0; i < line2.geometry.coordinates.length; i++) {
            const coordinate = line2.geometry.coordinates[i];
            pointList.push(coordinate)
        }
        return turf.lineString(pointList);
    }

    polygonsMer(geoJson) {
        const newGeoJson = {
            type: 'FeatureCollection',
            features: [{geometry: {coordinates: [], type: 'MultiPolygon'}, type: 'Feature', properties: {}}]
        };
        geoJson.geometry.coordinates.forEach(item => {
            item.map(i => {
                newGeoJson.features[0].geometry.coordinates.push(i);
            })
        });
        return newGeoJson;
    }


    submitSplitPlygin(resultPolygon1, resultPolygon2) {
        resultPolygon1 = turf.toMercator(resultPolygon1);
        resultPolygon2 = turf.toMercator(resultPolygon2);
        return new Promise((resolve) => {
            let plyginJson = [];
            this.plyginLayersList.map(plygin => {
                plygin.layerJson.features.map((fea, i) => {
                    if (fea.id === this.quiltSplitObject.geoFeature.id) {
                        const properties1 = this.quiltSplitObject.geoFeature.properties;
                        const properties2 = {...(properties1)};
                        resultPolygon1.properties = properties1;
                        resultPolygon2.properties = properties2;
                        if (resultPolygon2.properties.style === '#ffcc33') {
                            resultPolygon2.properties.style = '#0007E4';
                        } else {
                            resultPolygon2.properties.style = '#ffcc33';
                        }
                        plygin.layerJson.features.splice(i, 1);
                        plygin.layerJson.features.push(resultPolygon1);
                        plygin.layerJson.features.push(resultPolygon2);
                        plyginJson = plygin;
                        resolve(plyginJson)
                    }
                })
            });
        }).then(item => {
            this.quiltSplitObject.layer.getSource().removeFeature(this.splitObject.feature);
            this.editLayers(item);
            this.initSplit();
            this.unMapClickFun();
            this.tabsDisable('');
            this.message.success('区域拆分成功');
        })
    }

    initSplitPolygin() {
        this.showSplitSelectType = false;
        this.showMergeIcon = false;
        this.title = '';
        this.quiltSplitObject = {};
        this.splitObject = {};
    }

    initSplit() {
        this.splitFeatureColor = this.splitFeatureColor ? this.splitFeatureColor : '#ffcc33';
        this.quiltSplitObject.feature.setStyle(this.setPlictFeatureColor(this.splitFeatureColor));
        this.initSplitPolygin()
    }

    errorInitSplit() {
        this.quiltSplitObject.layer.getSource().removeFeature(this.splitObject.feature);
        this.splitFeatureColor = this.splitFeatureColor ? this.splitFeatureColor : '#ffcc33';
        this.quiltSplitObject.feature.setStyle(this.setPlictFeatureColor(this.splitFeatureColor));
        this.title = '请您在地图上选择要拆分的区域';
        this.showSplitSelectType = false;
        this.quiltSplitObject = {};
        this.splitObject = {};
        this.splitPolygon();
    }

    /**
     * 判断点是否在线里面
     * 注：线组成的坐标对比
     */
    isOnLine(point, line) {
        for (let i = 0; i < line.geometry.coordinates.length; i++) {
            const coordinate = line.geometry.coordinates[i];
            if (point.geometry.coordinates[0] === coordinate[0] && point.geometry.coordinates[1] === coordinate[1]) {
                return true;
            }
        }
        return false;
    }


    setPlictFeatureColor(style) {
        return new Style({
            fill: new Fill({
                color: style
            }),
        })
    }

    // 点击合并--获取面图层
    getPolygon() {
        this.mapClickFun = this.map.on('click', (evt) => {
            if (evt.dragging) {
                return;
            }
            this.displayFeatureInfo(evt.pixel).then((feature: any) => {
                if (feature) {
                    // 点击的第一个面 （合并以此面属性样式为主）  mergeFeature
                    if (!this.mergeFeature) {
                        this.mergeFeature = this.writeGeo(feature);
                        this.writeGeo(feature).geometry.coordinates.map(coor => {
                            this.mergefeatureCoorArray.push(coor)
                        });
                        //  点击的其他面 （都要被合并入第一个面） featureMerge
                    } else {
                        if (this.writeGeo(feature).id === this.mergeFeature.id) {
                            return
                        }
                        if (this.featureMerge.length !== 0) {
                            this.featureMerge.map(fea => {
                                if (this.writeGeo(feature).id === fea.id) {
                                    return;
                                } else {
                                    this.pushOtherFeater(feature)
                                }
                            })
                        } else {
                            this.pushOtherFeater(feature);
                        }

                    }
                    feature.setStyle(this.setFeatureColor('#a60a0abd'));
                    this.mergeFeature.geometry.coordinates = this.mergefeatureCoorArray;
                    return;
                } else {
                    this.message.create('error', `选中区域失败：请您放大地图重新选择`);
                    return
                }

            })
        });

    }


    pushOtherFeater(feature) {
        this.featureMerge.push(this.writeGeo(feature));
        this.writeGeo(feature).geometry.coordinates.map((coordinates: any) => {
            this.mergefeatureCoorArray.push(coordinates)
        });
    }

    // 点击地图上的某个面
    displayFeatureInfo(pixel) {
        return new Promise((resolve) => {
            this.map.forEachFeatureAtPixel(pixel, (feature: any) => {
                const layer = this.map.forEachLayerAtPixel(pixel, (layers: any) => {
                    return layers
                });
                if (!this.olUid) {
                    this.olUid = layer.ol_uid;
                }
                if (layer.ol_uid !== this.olUid) {
                    this.message.create('error', `请选择同一图层区域进行合并`);
                    return;
                }
                resolve(feature);
            });
        });
    };

    // 获取点、线、面的默认图层并触发画点、划线、画面交互
    getLayerAndAddDraw(drawType, type) {
        this.definLayerJson = this.getDefinLayersJson(drawType)[0]; // geojson数据的默认图层
        this.definLayer = this.getDefinLayersJson(drawType)[1];     // map数据的默认图层
        this.addDrawOrModifyInteraction(type, this.definLayerJson, this.definLayer);
    }

    // 添加绘制、修改交互
    addDrawOrModifyInteraction(type, layer, mapLayers) {
        return new Promise((resolve) => {
            this.draw = new Draw({
                source: mapLayers.getSource(),
                style: new Style({
                    fill: new Fill({
                        color: 'rgba(255, 255, 255, 0.2)'
                    }),
                    stroke: new Stroke({
                        color: '#ffcc33',
                        width: 2
                    }),
                    image: new CircleStyle({
                        radius: 7,
                        fill: new Fill({
                            color: '#ffcc33'
                        })
                    })
                }),
                type: type as any,
                geometryName: '我的第一个要素图形',
            });
            this.map.addInteraction(this.draw);
            resolve();
        }).then(() => {
            this.drawFun(type, layer, mapLayers)
        })
    }

    // 绘制之后的回调
    drawFun(type, layer, mapLayers) {
        this.currentMaplayers = mapLayers;
        this.currentLayer = layer;
        this.draw.on('drawstart', (e) => {
            this.currentFeature = e.feature;
            this.currentFeature.setStyle(new Style({
                fill: new Fill({
                    color: 'rgba(255, 255, 255, 0.2)'
                }),
                stroke: new Stroke({
                    color: '#ffcc33',
                    width: 2
                }),
                image: new CircleStyle({
                    radius: 7,
                    fill: new Fill({
                        color: '#ffcc33'
                    })
                })
            }));
            this.currentFeature.getGeometry().on('change', (evt) => {
                const geom = evt.target;
                if (geom instanceof Polygon) {
                    this.output = this.formatArea(geom);
                } else if (geom instanceof LineString) {
                    this.output = this.formatLength(geom);
                }
            });
        });

        this.draw.on('drawend', (e) => {
            this.currentFeature = e.feature;
            this.currentMaplayers.getSource().addFeature(this.currentFeature);
            this.showIcon = true;
            this.map.removeInteraction(this.draw);
        });
    }

    // 点击新建空图层
    newLayersFun(status: boolean) {
        this.layeryShow = status;
        this.layersFormInit();
    }

    // 添加空图层属性表单
    private layersFormInit() {
        this.layersForm = this.fb.group({
            layersName: [null, [Validators.required]],
            layersType: [null, [Validators.required]],
        });
    }

    // 添加空图层--关闭新建空图层弹框
    handleCancel() {
        this.layeryShow = false;
        this.loading = false;
    }

    // 添加空图层--确认提交添加空图层表单
    submitLayers() {
        this.loading = true;
        const layers = {
            layerType: this.layersForm.value.layersType,
            layerName: this.layersForm.value.layersName,
            layerJson: {
                'type': 'FeatureCollection',
                'features': []
            }
        };
        this.drawFeatureService.addNewLayers(layers).then(rep => {
            if (rep.resp_code === '10000') {
                this.editLayers(rep.data);
                this.layeryShow = false;
                this.message.success('新增图层成功', rep.resp_msg);
            } else {
                this.message.error(rep.resp_msg, rep.resp_msg);
            }
            this.loading = false;
        }).catch(err => {
            this.message.error('error', err);
            this.loading = false;
        });
    }

    // 修改图层
    editLayers(data) {
        this.drawFeatureService.editLayer(data).then(rep => {
            if (rep.resp_code === '10000') {
                if (this.layerID) {
                    this.getEditLayers(this.layerID);  // 获取编辑图层
                } else {
                    this.getSaveLayers();  // 获取图层列表
                }
            } else {
            }
        }).catch(err => {
            this.message.error('error', err);
        });
    }

    // 删除图层
    deleteLayers(id) {
        this.drawFeatureService.deteleLayers(id).then((rep) => {
            if (rep.resp_code === '10000') {
                this.message.success('删除图层成功', rep.resp_msg);
                this.layerID = '';
                this.getSaveLayers();  // 获取图层列表
            } else {
                this.message.error('删除图层失败', rep.resp_msg)
            }
        }).catch(err => {
            this.message.error('error', err);
        });
    }

    // 发布图层
    issueLayerUpDataFun() {
        this.layerID = '';
        this.getSaveLayers();
    }

    // 获取要素属性
    getFeatureAttr(e) {
        this.currentProperties = e;
    }

    emitColor(e) {
        this.setFStyle(e)
    }

    // 给要素设置颜色
    setFeatureColor(style) {
        return new Style({
            fill: new Fill({
                color: style
            }),
            stroke: new Stroke({
                color: style,
                width: 2
            }),
            image: new CircleStyle({
                radius: 7,
                fill: new Fill({
                    color: style
                })
            }),
        })
    }

    setFStyle(style) {
        if ((this.currentSelectMapFeature || (this.currSelectGeoLayer && this.currSelectGeoLayer.layerType === 1)) && (this.currentSelectMapFeature || (this.currSelectGeoLayer && this.currSelectGeoLayer.layerType === 2)) && (this.currentSelectMapFeature || (this.currSelectGeoLayer && this.currSelectGeoLayer.layerType === 3))) {
            style ? this.currentSelectMapFeature.setStyle(this.setFeatureColor(style)) : this.currentSelectMapFeature.setStyle(this.setFeatureColor(this.currentSelectMapFeatureColor));
        }
        if ((this.currentFeature || this.drawType === 2) && (this.currentFeature || this.drawType === 1) && (this.currentFeature || this.drawType === 3)) {
            style ? this.currentFeature.setStyle(this.setFeatureColor(style)) : this.currentFeature.setStyle(this.setFeatureColor('#ffcc33'));
        }
    }

    // 绘制完成
    isOK(showFeatureAttEdit) {
        if (showFeatureAttEdit) {
            this.message.create('error', `请先保存要素属性`);
            return
        }
        if (this.currentFeature) {
            if (this.currentProperties) {
                this.currentProperties.style = this.currentFeature.getStyle().getStroke().getColor();
            } else {
                this.currentProperties = {};
                this.currentProperties.style = '#ffcc33';
            }
            if (this.drawType === 3) {
                this.currentProperties.area = this.output
            } else if (this.drawType === 2) {
                this.currentProperties.lengths = this.output
            }
            this.currentFeature.setProperties(this.currentProperties, false);
            const geoFeatures = this.writeGeo(this.currentFeature);
            this.currentLayer.layerJson.features.push(geoFeatures);
            this.editLayers(this.currentLayer);
        }
        if (this.currentSelectMapFeature) {
            if (this.currentProperties) {
                this.currentProperties.style = this.currentSelectMapFeature.getStyle().getStroke().getColor();
            } else {
                this.currentProperties = {};
                this.currentProperties.style = this.currentSelectMapFeature.getStyle().getStroke().getColor();
            }
            this.currentSelectMapFeature.setProperties(this.currentProperties, false);
            const geoSelectFeatures = this.writeGeo(this.currentSelectMapFeature);
            for (let i = 0; i < this.currSelectGeoLayer.layerJson.features.length; i++) {
                if (this.currSelectGeoLayer.layerJson.features[i].id === geoSelectFeatures.id) {
                    this.currSelectGeoLayer.layerJson.features[i] = geoSelectFeatures;
                }
            }
            this.editLayers(this.currSelectGeoLayer);
            this.initMapView();
            this.tabsDisable('');
        }
        this.initDrawParameter();
    }

    // 点 X
    isClone(status?) {
        if (this.currentFeature) {  // 正在绘制---已经绘制删除
            this.currentMaplayers.getSource().removeFeature(this.currentFeature);
            this.currentFeature = null;
        }
        if (this.currentSelectMapFeature && !status) {  // 正在修改----点取消
            this.currentSelectMapFeature.setStyle(this.setFeatureColor(this.currentSelectMapFeatureColor));
            this.currentSelectMapFeature = null;
            this.initMapView();
            this.tabsDisable('');
        }
        if (this.currentSelectMapFeature && status === 'inEditDelete') { // 正在修改----点删除
            for (let i = 0; i < this.currSelectGeoLayer.layerJson.features.length; i++) {
                if (this.currSelectGeoLayer.layerJson.features[i].id === this.currentSelectFeature.id) {
                    this.currSelectGeoLayer.layerJson.features.splice(i, 1)
                }
            }
            this.editLayers(this.currSelectGeoLayer);
            this.currMapLayer.getSource().removeFeature(this.currentSelectMapFeature);
            this.currentSelectMapFeature = null;
            this.initMapView();
            this.tabsDisable('');
        }
        this.initDrawParameter();
    }

    initDrawParameter() {
        this.output = '';
        this.initRemoveInteraction();
        this.addFeatureModel = false;
        this.showIcon = false;
        this.currentFeature = null;
        this.currentProperties = null;
        this.currentSelectFeature = null;
        this.currentSelectMapFeature = null;
        this.tabsDisable('')
    }

    initMapView() {
        this.view.setCenter(fromLonLat([116.37, 39.89]));
        this.view.setZoom(Number(4));
    }

    // 列表选中要素
    selectFeatureFun(e) {
        if (this.drawType === 4 || this.drawType === 5) {
            this.message.create('error', `当前不能进行要素编辑`);
            return
        }
        this.tabsDisable(6);
        const featureId = e.feature.id;  // 当前要素id
        this.currSelectGeoLayer = this.getSelectLayer(e.layerid)[0]; // 当前选中图层
        this.currMapLayer = this.getSelectLayer(e.layerid)[1]; // 当前map图层
        this.currentSelectMapFeature = this.currMapLayer.getSource().getFeatureById(featureId);  // 当前map要素
        this.currentSelectMapFeatureColor = this.currentSelectMapFeature.getStyle().getStroke().getColor(); // 当前要素样式
        this.getSelectFeature(this.currSelectGeoLayer.layerJson.features, featureId).then((data: any) => {
            this.currentSelectFeature = data; // 当前选中要素数据集
            this.getSelectFeatureCoor(this.currSelectGeoLayer, featureId).then((item: any[]) => {
                if (this.currSelectGeoLayer.layerType === 1) {
                    this.view.setCenter(item);
                } else if (this.currSelectGeoLayer.layerType === 2) {
                    this.view.setCenter(item[0]);
                } else if (this.currSelectGeoLayer.layerType === 3) {
                    this.view.setCenter(item[0][0]);
                }
            });
            this.view.setZoom(Number(6));
            this.snap = new Snap({
                source: this.currMapLayer.getSource()
            });
            this.map.addInteraction(this.snap);
            this.modify = new Modify({
                source: this.currMapLayer.getSource(),
            });
            this.map.addInteraction(this.modify);
            this.select = new Select({
                wrapX: false
            });
            this.map.addInteraction(this.select);
            this.definLayerJson = this.currSelectGeoLayer;
            this.addFeatureModel = true;
            this.showIcon = true;
        })
    }

    // 根据要素id查某geo图层要素
    getSelectFeature(currGeoLayerLayerFeatuer, featureId) {
        return new Promise((resolve) => {
            for (let i = 0; i < currGeoLayerLayerFeatuer.length; i++) {
                let arr: any;
                if (currGeoLayerLayerFeatuer[i].id === featureId) {
                    arr = currGeoLayerLayerFeatuer[i];
                    resolve(arr);
                    return
                }
            }
        })
    }

    // 根据featureId查找某geo图层里面某要素的经纬度
    getSelectFeatureCoor(currGeoLayer, featureId) {
        return new Promise((resolve) => {
            for (let i = 0; i < currGeoLayer.layerJson.features.length; i++) {
                if (currGeoLayer.layerJson.features[i].id === featureId) {
                    resolve(currGeoLayer.layerJson.features[i].geometry.coordinates);
                    return;
                }
            }
        })
    }

    // 根据layerid查找geo某图层
    getSelectLayer(layerid) {
        for (let i = 0; i < this.allLayersListData.length; i++) {
            if (this.allLayersListData[i].layerId === layerid) {
                return [this.allLayersListData[i], this.mapAllLayersListData[i]];
            }
        }
    }

    // 获取默认第一个点\线\面json图层（地图真实图层，交互数据图层）
    getDefinLayersJson(type) {
        for (let i = 0; i < this.allLayersListData.length; i++) {
            if (this.allLayersListData[i].layerType === 1 && type === 1) {
                return [this.allLayersListData[i], this.mapAllLayersListData[i]];
            } else if (this.allLayersListData[i].layerType === 2 && type === 2) {
                return [this.allLayersListData[i], this.mapAllLayersListData[i]];
            } else if (this.allLayersListData[i].layerType === 3 && type === 3) {
                return [this.allLayersListData[i], this.mapAllLayersListData[i]];
            }
        }
    }

    visibility(e) {
        this.currVisibilityMapLayer = this.getSelectLayer(e[0])[1]; // 当前map图层
        if (e[1] === null) {
            this.currVisibilityMapLayer.setVisible(!this.currVisibilityMapLayer.getVisible());
            return;
        } else if (e[1] === true) {
            this.currVisibilityMapLayer.setVisible(true);
        } else {
            this.currVisibilityMapLayer.setVisible(false);
        }
    }

    writeGeo(feature) {
        return this.geo.writeFeatureObject(feature, {});
    }

    // remove交互功能
    initRemoveInteraction() {
        this.map.removeInteraction(this.draw);
        this.map.removeInteraction(this.snap);
        this.map.removeInteraction(this.modify);
    }


    removeMapLayerAndInteraction() {
        this.map.getLayers().getArray().slice(1).map(data => {
            this.map.removeLayer(data);
            this.initRemoveInteraction();
        });
        this.unMapClickFun();
    }


    initDrawPara(drawType, type) {
        this.tabsDisable(drawType);
        this.drawType = drawType;
        this.addFeatureModel = true;
        this.initSplitPolygin();
        this.leaveMergeInit();
        this.getLayerAndAddDraw(this.drawType, type);
    }

    initMergeAndSplitPara(drawType) {
        this.drawType = drawType;
        this.addFeatureModel = false;
        this.showMergeIcon = true;
        this.getMapAllLayryArrar();
    }

    leaveMergeInit() {
        this.initMergeParameter();
        this.showMergeIcon = false;
        this.unMapClickFun()
    }

    initMergeParameter() {
        this.plyginLayersList = [];
        this.mergeFeature = null;
        this.mergefeatureCoorArray = [];
        this.featureMerge = [];
        this.olUid = '';
    }

    unMapClickFun() {
        this.map.removeEventListener('click', null)
    }

    public tabsDisable(title?: any) {
        this.tabArr.map(tab => {
            if (title === '') {
                tab.tabStatus = false;
                return;
            } else if (title === tab.index) {
                tab.tabStatus = false
            } else {
                tab.tabStatus = true
            }
        })
    }

    formatLength = (line) => {
        const lineCopy = line.clone();
        lineCopy.applyTransform(getTransform('EPSG:3857', 'EPSG:3857'));
        const length = getLength(lineCopy);
        let output;
        output = (Math.round(length * 100) / 100);
        return output;
    };

    formatArea = (polygon) => {
        const polygonCopy = polygon.clone();
        polygonCopy.applyTransform(getTransform('EPSG:3857', 'EPSG:3857'));
        const area = getArea(polygonCopy);
        let output;
        output = (Math.round(area * 100) / 100);
        return output;
    };

}


/**
 * multiPolygon转polygons,不涉及属性
 */
// multiPolygon2polygons(multiPolygon) {
//     if (multiPolygon.geometry.type !== 'MultiPolygon') {
//         return
//     }
//     const polygons = [];
//     multiPolygon.geometry.coordinates.forEach((item) => {
//         const polygon = {
//             type: 'Feature',
//             properties: {},
//             geometry: {
//                 type: 'Polygon',
//                 coordinates: []
//             }
//         };
//         polygon.geometry.coordinates = item;
//         polygons.push(polygon)
//     });
//     return polygons;
// }


// // 若输入的多边形类型为Multipolygon则拆分成多个Polygon
// const polygons: any = this.multiPolygon2polygons(polygon);
// let clipPolygon = null;
// let clipPolygonIndex = -1;
// // 获取MultiPolygon中与切割线相交的多边形（有且只能有一个多边形相交2个交点）
// polygons.forEach((polygon, index) => {
//     const polyLine = turf.polygonToLine(polygon);
//     if (turf.lineIntersect(polyLine, clipLine).features.length === 2) {
//         if (!clipPolygon) {
//             clipPolygon = polygon;
//             clipPolygonIndex = index;
//         } else {
//             this.message.create('error', `裁剪失败:MultiPolygon只能有一个多边形与切割线存在交点`);
//             this.initSplit()
//         }
//     }
// });
// if (clipPolygonIndex !== -1) {
//     polygons.splice(clipPolygonIndex, 1);
//     return turf.featureCollection(polygons.concat(this.polygonClipByLine(clipPolygon, clipLine).features));
// } else {
//     this.message.create('error', `裁剪失败:MultiPolygon与切割线无交点`);
//     this.initSplit()
// }
